<template>
  <div class="bg-white _p-20">
    <div class="fz-16 title linh-48 _mb-10">
      报名设置<span class="fz-14 _ml-10" style="color: #FF7D00;"
        >报名默认是无需审核，如需审核请到对应报名类型修改审核设置</span
      >
    </div>
    <div class="box">
      <a-table bordered :data-source="form.ticketTypeConfigList" :columns="columns" :pagination="false">
        <template slot="ticketNameTitle">
          <a-popover title="报名类型说明" trigger="hover">
            <template slot="content">
              <p>用户可以选择其中一个报名类型，可以按活动场次或参会身份等分类设定不同报名类型</p>
              <p>例如:会员大会、晚宴、会员大会+晚宴；会员报名、嘉宾报名、志愿者报名等。</p>
              <p style="color: #165DFF;cursor: pointer;" @click="handlePreviewImg()">
                多个报名类型情况下的展示效果预览 >
              </p>
            </template>
            报名类型
            <a-icon type="question-circle" style="color:#FF7D00" />
          </a-popover>
        </template>
        <template slot="stockNumTitle">
          <a-popover title="报名名额说明" trigger="hover">
            <template slot="content">
              <p>所有报名类型叠加后的报名名额不可大于活动的“限制报名人数”设定的人数；</p>
              <p>报名名额输入为空设定为不限制名额（不会超出限制报名人数）；</p>
              <p>输入为0设定报名名额清空为0；</p>
            </template>
            报名名额
            <a-icon type="question-circle" style="color:#FF7D00" />
          </a-popover>
        </template>

        <template slot="ticketName" slot-scope="text, record">
          <EditableCell
            :text="text.toString()"
            width="auto"
            :editStyle="{ marginTop: 0, right: '40px' }"
            :disabled="disableEditing"
            @change="handleEditChange(record, $event, 'ticketName')"
          ></EditableCell>
        </template>
        <template slot="stockNum" slot-scope="text, record">
          <EditableCell
            :text="text"
            width="auto"
            placeholder="不限制"
            :editStyle="{ marginTop: 0, right: '40px' }"
            :disabled="disableEditing"
            @change="handleEditChange(record, $event, 'stockNum')"
          >
          </EditableCell>
        </template>
        <template slot="reviewStatus" slot-scope="text, record">
          <a-select
            :value="text"
            style="width: 100%;"
            @change="handleEditChange(record, $event, 'reviewStatus')"
            :disabled="disableEditing"
          >
            <a-select-option v-for="(item, index) in isReviewOptions" :value="item.dictValue" :key="index">
              {{ item.dictLabel }}
            </a-select-option>
          </a-select>
        </template>
        <template slot="action" slot-scope="text, record">
          <div class="disFlx">
            <a-button
              v-if="!disableEditing"
              type="primary"
              class="_mr-10 cup"
              ghost
              @click="handleOpenEdit(record, record.ticketType)"
            >
              更多设置
            </a-button>
            <a-popconfirm
              v-if="!disableEditing"
              :title="`确定要删除报名类型“${record.ticketName}“?`"
              ok-text="确定删除"
              cancel-text="取消"
              @confirm="handleDel(record.webId)"
            >
              <a-button v-if="!disableEditing" type="danger" ghost>
                删除
              </a-button>
            </a-popconfirm>
          </div>
        </template>
      </a-table>
      <div class="box-bottom">
        <div class="return-ticket">
          <a-form-model
            ref="form"
            :model="form"
            :rules="rules"
            :labelCol="{
              xs: { span: 24 },
              sm: { span: 6 }
            }"
            :wrapperCol="{
              xs: { span: 24 },
              sm: { span: 14 }
            }"
          >
            <a-form-model-item label="取消报名设置" prop="refundTicketType">
              <a-radio-group v-model="form.refundTicketType" :disabled="disableEditing">
                <a-radio
                  v-for="(item, index) in RefundTicketTypeEnumDict"
                  :key="index"
                  :value="item.value"
                  :style="radioStyle"
                >
                  <template v-if="item.value === RefundTicketTypeEnum.Custom">
                    <div style="display: inline-block;">
                      <span> {{ item.label }}</span>
                      <a-input class="_mr-10 fz-12 _ml-10" style="width:120px;" v-model="form.refundTicketHour">
                        <span slot="addonAfter" class="fz-12">小时</span>
                      </a-input>
                      <span>不允许申请取消报名</span>
                    </div>
                  </template>
                  <template v-else>
                    <span>{{ item.label }}</span>
                  </template>
                </a-radio>
              </a-radio-group>
            </a-form-model-item>
          </a-form-model>
        </div>
        <div v-if="!disableEditing" class="btns">
          <a-button type="primary" @click="handleOpenEdit(null, TicketTypeEnum.free)">
            <a-icon type="plus" />添加普通类型
          </a-button>
          <a-button type="primary" @click="handleOpenEdit(null, TicketTypeEnum.pay)">
            <a-icon type="plus" /> 添加付费类型
          </a-button>
        </div>
      </div>
    </div>
    <TicketSetForm ref="ticketSetFormRef" @save="handleSave"></TicketSetForm>

    <a-modal v-model="previewObj.visible" width="300px" :footer="null">
      <viewer :images="[previewObj.previewImg]">
        <img :src="previewObj.previewImg" width="100%" />
      </viewer>
    </a-modal>
  </div>
</template>

<script>
import EditableCell from '@/components/EditableCell'
import TicketSetForm from './TicketSetForm'
import {
  ReviewStatusEnum,
  StockLimitEnum,
  BuyLimitEnum,
  BuyTimeTypeEnum,
  BuyIdentityLimitEnum,
  EnabledMemberDiscountEnum,
  ActivityMemberLevelEnum,
  RefundTicketTypeEnum,
  TicketTypeEnum,
  ActivitySettlementStatusEnum
} from '@/enums/activity'
import { validCreatePayTicket, getUnionMemberLevelList } from '@/api/activity/activity.js'
import { intRegex } from '@/utils/RegExp.js'
import { cloneDeep } from 'lodash'
import { isOpenPay } from '@/utils/codes'
import { is0, isEmpty } from '@/utils/is'
import { buildUUID } from '@/utils/uuid'
const initRecord = {
  webId: buildUUID(),
  /**活动id */
  activityUnionId: undefined,
  activityId: undefined,
  /**票id */
  id: undefined,
  /**票类型 */
  ticketType: TicketTypeEnum.free,
  /**票名称 */
  ticketName: '普通类型',
  /**票种说明*/
  introduction: undefined,
  /**价格 */
  price: 0,
  /**库存限制 */
  stockLimit: StockLimitEnum.NO,
  /**可用库存 */
  stockNum: undefined,
  /**购票限制 */
  buyLimit: BuyLimitEnum.NO,
  /**最大购买限制 */
  buyMaxNum: undefined,
  /**最小购买限制 */
  buyMinNum: 1,
  /**是否需要审核 */
  reviewStatus: ReviewStatusEnum.NO,
  /**购票时间类型 */
  buyTimeType: BuyTimeTypeEnum.activityEndTime,
  /**开始时间 */
  startTime: undefined,
  /**结束时间 */
  endTime: undefined,
  /**购买身份限制 */
  buyIdentityLimit: BuyIdentityLimitEnum.NO,
  /**是否隐藏 0 隐藏 1不隐藏 */
  display: 1,
  /**是否开启会员优惠 */
  enabledMemberDiscount: EnabledMemberDiscountEnum.NO,
  /**备注 */
  remarks: undefined,
  memberIdentityConfigList: [],
  memberDiscountConfigList: []
}
export default {
  components: {
    EditableCell,
    TicketSetForm
  },
  props: {
    info: {
      type: Object,
      default: () => ({})
    },
    enrollRestrict: {
      type: Number,
      default: 0
    },
    maxNum: {
      type: Number,
      default: 0
    },
    endTime: {
      type: String,
      default: ''
    },
    startTime: {
      type: String,
      default: ''
    }
  },

  computed: {
    disabled() {
      return this.info.activityType === 'other_join' // 协办方
    },
    RefundTicketTypeEnumDict() {
      return this.Dict.getLocalMap('RefundTicketTypeEnumDict', 'label', 'value')
    },
    disableEditing() {
      return (
        [
          ActivitySettlementStatusEnum.PROGRESS,
          ActivitySettlementStatusEnum.SUCCESS,
          ActivitySettlementStatusEnum.PART_SUCCESS
        ].includes(this.info.settleStatus) || this.disabled
      )
    }
  },
  watch: {
    info: {
      handler(val) {
        this.form.refundTicketHour = val.refundTicketHour || 0
        this.form.refundTicketType = val.refundTicketType || RefundTicketTypeEnum.Custom
        if (val && val.ticketTypeConfigList && val.ticketTypeConfigList.length) {
          this.form.ticketTypeConfigList = val.ticketTypeConfigList.map(item => ({
            ...item,
            webId: buildUUID()
          }))
        } else {
          this.form.ticketTypeConfigList = [
            {
              ...cloneDeep(initRecord),
              activityId: this.$route.query.activityId
            }
          ]
        }
      },
      deep: true,
      immediate: true
    },
    'form.refundTicketHour': {
      handler(val) {
        this.$refs.form.validateField('refundTicketType')
      }
    }
  },
  data() {
    return {
      previewObj: {
        previewImg: 'https://hb-saas.obs.cn-south-1.myhuaweicloud.com/mall/saas/ticketType_example.png',
        visible: false
      },
      previewImg: '',
      RefundTicketTypeEnum,
      TicketTypeEnum,
      StockLimitEnum,
      radioStyle: {
        display: 'block',
        height: '40px',
        lineHeight: '40px',
        width: 'fit-content'
      },
      rules: {
        refundTicketType: [
          {
            trigger: ['change', 'blur'],
            validator: (rule, value, callback) => {
              if (value == RefundTicketTypeEnum.Custom) {
                if (!intRegex.test(this.form.refundTicketHour)) {
                  callback('请输入整数数字')
                }
                if (isEmpty(this.form.refundTicketHour)) {
                  callback('请填写取消报名时间')
                }
              }
              callback()
            }
          }
        ]
      },
      form: {
        refundTicketHour: undefined,
        refundTicketType: undefined,
        ticketTypeConfigList: []
      },
      memberIdentityConfigList: [],
      memberDiscountConfigList: [],
      isReviewOptions: this.Dict.getLocal('ReviewStatusEnumDict'),
      columns: [
        {
          dataIndex: 'ticketName',
          slots: { title: 'ticketNameTitle' },
          scopedSlots: { customRender: 'ticketName' }
        },
        {
          title: '报名费用（元）',
          dataIndex: 'price',
          customRender: text => (text == 0 ? '无' : text)
        },
        {
          dataIndex: 'stockNum',
          slots: { title: 'stockNumTitle' },
          scopedSlots: { customRender: 'stockNum' },
          width: 280
        },
        {
          title: '审核设置',
          dataIndex: 'reviewStatus',
          scopedSlots: { customRender: 'reviewStatus' },
          width: 280
        },
        {
          title: '操作',
          key: 'action',
          scopedSlots: { customRender: 'action' },
          width: 160
        }
      ]
    }
  },
  mounted() {
    this.queryUnionMemberLevelList(ActivityMemberLevelEnum.Identity)
    this.queryUnionMemberLevelList(ActivityMemberLevelEnum.Discount)
  },
  methods: {
    handlePreviewImg() {
      this.previewObj.visible = true
    },
    stockLimitMax(webId) {
      return this.form.ticketTypeConfigList
        .filter(item => item.webId != webId)
        .reduce(
          (preV, currV) => {
            if (currV.stockLimit === StockLimitEnum.YES) {
              return preV - currV.stockNum
            }
            return preV
          },
          this.enrollRestrict ? this.maxNum : Number.MAX_SAFE_INTEGER
        )
    },
    async handleEditChange(record, value, key) {
      const originalVal = record[key]
      record[key] = value
      if (['stockNum'].includes(key)) {
        this.$nextTick(() => {
          if (isNaN(Number(value))) {
            record[key] = originalVal
            return
          }
          if (Number(value) > Number(this.stockLimitMax(record.webId)) && !isEmpty(value) && !is0(value)) {
            record[key] = originalVal
            this.$message.error('报名名额不能超过剩余最大报名人数')
            return
          }
          record[key] = value
          if (!isEmpty(value)) {
            record.stockLimit = StockLimitEnum.YES
          } else {
            record.stockLimit = StockLimitEnum.NO
          }
        })
        return
      }
    },

    async handleOpenEdit(record, ticketType) {
      if (ticketType == TicketTypeEnum.pay) {
        const res = await validCreatePayTicket({ activityId: this.$route.query.activityId })
        if (res.code === isOpenPay) {
          await this.openConfirm({
            title: '添加付费类型提示',
            content: '本组织暂未开通支付，不可添加付费类型',
            okText: '前往开通'
          })
          this.$router.push({
            path: '/system/paySettings',
            query: {
              titleKey: 'onlinePayment'
            }
          })
        }
        if (res.code) return

        if (!this.form.ticketTypeConfigList.some(item => item.ticketType === TicketTypeEnum.pay)) {
          await this.openConfirm({
            title: '添加付费类型提示',
            content:
              '确定要添加付费类型吗？添加了付费类型之后，本活动将无法跨会互通，无法邀请协办组织合作一起举办活动。',
            okText: '确定添加'
          })
        }
      }

      if (!record) {
        record = {
          ...initRecord,
          webId: buildUUID(),
          ticketName: ticketType == TicketTypeEnum.pay ? '付费类型' : '普通类型',
          price: ticketType == TicketTypeEnum.pay ? undefined : 0,
          ticketType
        }
      }

      this.$refs.ticketSetFormRef.open({
        info: this.info,
        ticketTypeConfigList: this.form.ticketTypeConfigList,
        enrollRestrict: this.enrollRestrict,
        maxNum: this.maxNum,
        endTime: this.endTime,
        startTime: this.startTime,
        activityType: this.info.activityType,
        settleStatus: this.info.settleStatus,
        record: cloneDeep(record),
        memberIdentityConfigList: this.memberIdentityConfigList,
        memberDiscountConfigList: this.memberDiscountConfigList
      })
    },
    async handleDel(webId) {
      if (this.form.ticketTypeConfigList.length === 1) {
        this.$message.error('至少需要存在一种报名类型')
        return
      }
      this.form.ticketTypeConfigList = this.form.ticketTypeConfigList.filter(item => item.webId !== webId)
    },
    handleSave(formData) {
      const index = this.form.ticketTypeConfigList.findIndex(item => item.webId === formData.webId)
      if (index === -1) {
        this.form.ticketTypeConfigList.push(formData)
      } else {
        this.$set(this.form.ticketTypeConfigList, index, formData)
      }
    },
    async saveForm() {
      if (this.form.ticketTypeConfigList.some(item => item.ticketType === TicketTypeEnum.pay)) {
        return this.openConfirm({
          title: '保存活动提示',
          okText: '依然保存',
          content: h => {
            return h(
              'span',
              '本活动创建了付费类型，如果要创建活动，当前活动将不可以跨会合作，确定当前活动不需要跨会请点击“依然创建”。如果活动需要跨会合作，请先将付费类型删除后再保存创建活动。'
            )
          }
        }).then(() => Promise.resolve(this.form))
      }

      return Promise.resolve(this.form)
    },
    openConfirm({ title, okText, content, cancelText = '取消' }) {
      return new Promise((resolve, reject) => {
        this.$confirm({
          title,
          okText,
          content,
          cancelText,
          icon: 'exclamation-circle',
          onOk() {
            resolve('Ok')
          },
          onCancel() {
            reject('Cancel')
          }
        })
      })
    },
    async queryUnionMemberLevelList(type) {
      const res = await getUnionMemberLevelList({ type })
      if (type === ActivityMemberLevelEnum.Identity) {
        this.memberIdentityConfigList = res.data
      } else {
        this.memberDiscountConfigList = res.data.map(item => {
          return {
            memberLevelId: item.memberLevelId,
            memberLevelName: item.memberLevelName,
            price: this.form.price,
            errMsg: ''
          }
        })
      }
    }
  }
}
</script>

<style lang="less" scoped>
.title {
  color: #1d2129;
  border-bottom: solid 1px #e5e6eb;
}

.tips {
  color: #86909c;
}

.box {
  .box-bottom {
    padding: 16px 32px;

    .btns {
      display: flex;
      justify-content: center;
      gap: 8px;
    }
  }
}
</style>
